﻿using FastEventBus.Definition;
using FastEventBus.Entity;
using FastUtil.Log;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace FastEventBus.Handle
{
    public class EventSession
    {
        public IFastEventStroage Stroage;

        public void Subscribe(IFastEventHandler Handler)
        {
            Stroage.RegistHandler(Handler);
        }

        public void Publish(string ChannelName, Dictionary<string, object> EventParamDic)
        {
            FastEventParam EventEntity = new FastEventParam();
            EventEntity.ChannelName = ChannelName;
            foreach (var item in EventParamDic)
            {
                EventEntity.AddParam(item.Key, item.Value);
            }
            Stroage.WriteEvent(EventEntity);

            Task.Run(() =>
            {
                List<IFastEventHandler> HandlerList = Stroage.ResolveHandler(ChannelName);
                foreach (IFastEventHandler Handler in HandlerList)
                {
                    try
                    {
                        if (!Handler.Check(EventEntity))
                        {
                            Handler.Handle(EventEntity);
                        }
                    }
                    catch (System.Exception e)
                    {
                        StringBuilder ExceptionLog = new StringBuilder();
                        ExceptionLog.AppendFormat("EventHandler：{0}发生异常", Handler.GetType().FullName + Environment.NewLine);
                        ExceptionLog.AppendFormat("EventHandler异常所属Channel：{0}", ChannelName + Environment.NewLine);
                        ExceptionLog.AppendFormat("EventHandler异常信详细：{0}", Environment.NewLine + e.Message);
                        ExceptionLog.AppendFormat("========================================================================================================================================================================" + Environment.NewLine);
                        LogUtil.WriteLog("Logs/EventBusError", "log_", ExceptionLog.ToString() + Environment.NewLine);
                    }
                    finally
                    {
                        Stroage.ACKEvent(EventEntity.ChannelName, EventEntity.EventID);
                    }
                }

            });
        }
    }
}
